﻿namespace ImageProcessing
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;

    /// <summary>
    /// Quantization Class
    /// </summary>
    public partial class Quantization : Form
    {
        /// <summary>
        /// True if the user Press Ok
        /// </summary>
        private bool ok = false;
      
        /// <summary>
        /// Reference to the image
        /// </summary>
        private DImage image;
       
        /// <summary>
        /// array of red bits
        /// </summary>
        private char[] redValue = { '1', '1', '1', '1', '1', '1', '1', '1' };
      
        /// <summary>
        /// array of green bits
        /// </summary>
        private char[] greenValue = { '1', '1', '1', '1', '1', '1', '1', '1' };
       
        /// <summary>
        /// array of blue bits
        /// </summary>
        private char[] blueValue = { '1', '1', '1', '1', '1', '1', '1', '1' };
       
        /// <summary>
        /// Initializes a new instance of the <see cref="Quantization"/> class.
        /// </summary>
        /// <param name="i">The i.</param>
        public Quantization(DImage i)
        {
            this.InitializeComponent();
            this.image = i;
            this.image.BackupImageArray();
            this.Pcb_Original.Image = this.Pcb_Modified.Image = Operations.DisplayMatrix(ResizeImage.BicubicResize(this.Pcb_Original.Size.Width, this.Pcb_Original.Size.Height, this.image.ImageStructArray, 3));
            this.FillPanelsWithPics();

            if (this.image.GreyScale)
            {
                this.Hide2Panles();
            }
        }

        /// <summary>
        /// Fills the panels with pics.
        /// </summary>
        private void FillPanelsWithPics()
        {
            // Red
            this.image.ImageStructArray = ResizeImage.BicubicResize(this.Pnl_Blu0.Size.Width, this.Pnl_Blu0.Size.Height, this.image.ImageStructArray, 3);
            this.Pnl_Red0.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 0, 'R', this.image.GreyScale));
            this.Pnl_Red1.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 1, 'R', this.image.GreyScale));
            this.Pnl_Red2.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 2, 'R', this.image.GreyScale));
            this.Pnl_Red3.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 3, 'R', this.image.GreyScale));
            this.Pnl_Red4.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 4, 'R', this.image.GreyScale));
            this.Pnl_Red5.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 5, 'R', this.image.GreyScale));
            this.Pnl_Red6.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 6, 'R', this.image.GreyScale));
            this.Pnl_Red7.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 7, 'R', this.image.GreyScale));

            // Green
            this.Pnl_Grn0.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 0, 'G', this.image.GreyScale));
            this.Pnl_Grn1.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 1, 'G', this.image.GreyScale));
            this.Pnl_Grn2.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 2, 'G', this.image.GreyScale));
            this.Pnl_Grn3.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 3, 'G', this.image.GreyScale));
            this.Pnl_Grn4.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 4, 'G', this.image.GreyScale));
            this.Pnl_Grn5.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 5, 'G', this.image.GreyScale));
            this.Pnl_Grn6.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 6, 'G', this.image.GreyScale));
            this.Pnl_Grn7.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 7, 'G', this.image.GreyScale));

            // Blue
            this.Pnl_Blu0.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 0, 'B', this.image.GreyScale));
            this.Pnl_Blu1.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 1, 'B', this.image.GreyScale));
            this.Pnl_Blu2.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 2, 'B', this.image.GreyScale));
            this.Pnl_Blu3.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 3, 'B', this.image.GreyScale));
            this.Pnl_Blu4.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 4, 'B', this.image.GreyScale));
            this.Pnl_Blu5.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 5, 'B', this.image.GreyScale));
            this.Pnl_Blu6.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 6, 'B', this.image.GreyScale));
            this.Pnl_Blu7.BackgroundImage = Operations.DisplayMatrix(MaskBits.DisplayBit(this.image.ImageStructArray, 7, 'B', this.image.GreyScale));
        }

        /// <summary>
        /// Handles the Click event of the Pnl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void Pnl_Click(object sender, EventArgs e)
        {
            Panel pnl = (Panel)sender;
            bool pnlChecked = false;

            string colorString = pnl.Name.Substring(4, 1);
            char color = colorString[0];
            int bitNumber = int.Parse(pnl.Name.Substring(7, 1));

            if (pnl.BorderStyle == BorderStyle.Fixed3D)
            {
                pnlChecked = false;
                pnl.BorderStyle = BorderStyle.None;
            }
            else
            {
                pnlChecked = true;
                pnl.BorderStyle = BorderStyle.Fixed3D;
            }

            if (this.image.GreyScale)
            {
                this.redValue[bitNumber] = pnlChecked ? '1' : '0';
                this.greenValue[bitNumber] = pnlChecked ? '1' : '0';
                this.blueValue[bitNumber] = pnlChecked ? '1' : '0';
            }
            else if (color == 'R')
            {
                this.redValue[bitNumber] = pnlChecked ? '1' : '0';
            }
            else if (color == 'G')
            {
                this.greenValue[bitNumber] = pnlChecked ? '1' : '0';
            }
            else
            {
                this.blueValue[bitNumber] = pnlChecked ? '1' : '0';
            }

            this.UpdateModified();
        }

        /// <summary>
        /// Updates the modified image.
        /// </summary>
        private void UpdateModified()
        {
            this.image.RetriveImageArray();
            this.image.ImageStructArray = MaskBits.RemoveBits(this.image.ImageStructArray, this.redValue, this.greenValue, this.blueValue);
            this.Pcb_Modified.Image = Operations.DisplayMatrix(ResizeImage.BicubicResize(this.Pcb_Original.Size.Width, this.Pcb_Original.Size.Height, this.image.ImageStructArray, 3));

            Array.Reverse(this.redValue);
            Array.Reverse(this.greenValue);
            Array.Reverse(this.blueValue);
            this.Lbl_RedValue.Text = new string(this.redValue);
            this.Lbl_GreenValue.Text = new string(this.greenValue);
            this.Lbl_BlueValue.Text = new string(this.blueValue);
            Array.Reverse(this.redValue);
            Array.Reverse(this.greenValue);
            Array.Reverse(this.blueValue);
        }

        /// <summary>
        /// Handles the Click event of the BtnCancel control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The instance containing the event data.</param>
        private void BtnCancel_Click(object sender, EventArgs e)
        {
            this.image.RetriveImageArray();
            this.Close();
        }

        /// <summary>
        /// Handles the Click event of the BtnOk control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The instance containing the event data.</param>
        private void BtnOk_Click(object sender, EventArgs e)
        {
            this.ok = true;
            this.image.UpdateImage();
            this.Close();
        }

        /// <summary>
        /// Handles the FormClosed event of the Quantization control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The instance containing the event data.</param>
        private void Quantization_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (!this.ok)
            {
                this.image.RetriveImageArray();
            }
        }

        /// <summary>
        /// Hide2s the panles.
        /// </summary>
        private void Hide2Panles()
        {
            this.Pnl_Blu0.Visible = false;
            this.Pnl_Blu1.Visible = false;
            this.Pnl_Blu2.Visible = false;
            this.Pnl_Blu3.Visible = false;
            this.Pnl_Blu4.Visible = false;
            this.Pnl_Blu5.Visible = false;
            this.Pnl_Blu6.Visible = false;
            this.Pnl_Blu7.Visible = false;
            this.Pnl_Grn0.Visible = false;
            this.Pnl_Grn1.Visible = false;
            this.Pnl_Grn2.Visible = false;
            this.Pnl_Grn3.Visible = false;
            this.Pnl_Grn4.Visible = false;
            this.Pnl_Grn5.Visible = false;
            this.Pnl_Grn6.Visible = false;
            this.Pnl_Grn7.Visible = false;

            this.Lbl_Blue.Text = "Gray";
            this.Lbl_Green.Visible = false;
            this.Lbl_GreenValue.Visible = false;
            this.Lbl_Red.Visible = false;
            this.Lbl_BlueValue.Visible = false;
        }   
    }
}
